/*------------------------------------------------------------------------------------------------------------------*/
float t; 
float t0;
pt C = new pt(); 
int nr=1;                       
Rectangle R [] = new Rectangle [nr];   
Point usrMouse = new Point(); 
/*------------------------------------------------------------------------------------------------------------------*/
public void updatePoints(float cm1, float cm2)   {   
  float mc1=cm1;
  float mc2=cm2; 
  t=millis()-t0; 
  t0=millis(); // t=time from last frame, usually between 5 and 15
  usrMouse.update(cm1, cm2);    
  for (int i=0; i<nr; i++) { 
    if (R[i].picked)  R[i].track(); 
  }; 
  for (int i=0; i<nr; i++) {
    R[i].paint();  
  };
  vec W = new vec();   
}
/*------------------------------------------------------------------------------------------------------------------*/
public void createObject(float x1, float x2, float x3, float x4, float x5) { 
  stroke(255); 
   R[0] = new Rectangle(x2,x1,color(#000000));
  /*
   R[1] = new Rectangle(x2,x3,color(#000000));
   R[2] = new Rectangle(x4,x1,color(#000000));
   R[3] = new Rectangle(x4,x3,color(#000000));
   R[4] = new Rectangle(x5,x1,color(#000000));
   R[5] = new Rectangle(x5,x3,color(#000000));
 */
}

class Rectangle {  
  pt  O = new pt(400,400);             // origin 
  vec V = new vec(0,0);                // velocity
  vec R0= new vec(0,0);                // picked position in body coord.
  float a=0.0, dadt=0.0;               // angle and angular speed 
  float h=200, w=250;                    // dimensions
  vec I=new vec(1,0), J=new vec(0,1);  // local CS
  boolean picked = false;              // true if being dragged
  color col;                           // color
  float Mass = .001;
  float Inertia = (h*h*h*w + h*w*w*w)/3 * (Mass/w/h);
  Rectangle (float px, float py, color pc) {O.x=px; O.y=py; col=pc;};  // create from position and color
  Rectangle (float px, float py, float pa, color pc) {a=pa; O.x=px; O.y=py; col=pc;};  // create from position and color  beginShape();
  void move () { 
     O.addVec(V);
     this.updateBasis();    
     };                     
public void updateBasis() {I.x=cos(a); I.y=sin(a); J.x=-sin(a); J.y=cos(a);};// reco,putes basis by rotating by a
public void paint() {pushMatrix(); translate(O.x,O.y); rotate(a);  fill(col,150); if(picked) fill(255,50); rect(0,0,2*w,2*h);  popMatrix(); }; 
boolean mouseIsIn(float cm1, float cm2) {pt N = new pt(); 
N.setToMouse(cm1,cm2);
vec D=O.vecTo(N); float x=dot(I,D); float y=dot(J,D);  return((abs(x)<w)&&(abs(y)<h)); }; // true if mouse in rectangle

public void register(float cm3, float cm4) {
    if(this.mouseIsIn(cm3,cm4)) {
      picked=true;
      dadt = 0;
      usrMouse.P.setToMouse(cm3,cm4);
      vec RR = O.vecTo(usrMouse.P);
      R0.x = RR.x*I.x + RR.y*I.y; 
      R0.y = RR.x*J.x + RR.y*J.y; 
      };
    }      

  public void track() {
    float dt = .3;
    vec R = R0.turn(a);
    float alp = - (Mass)/(Mass*R.norm()+Inertia) * (usrMouse.V.x*R.y - usrMouse.V.y*R.x);
    dadt += dt * alp - 0.1*dadt; // increment angular velocity 
    a    += dt * dadt;
    R = R0.turn(a);
    O.setTo(usrMouse.P);    O.subVec(R);
    this.updateBasis(); 
    }
  }   
